package br.com.tmd.controlefinanceiro.persistence;

import br.com.tmd.controlefinanceiro.util.HibernateUtil;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

abstract public class GenericDao<E> implements InterfaceDao<E> {

    Session session;
    Transaction transaction;
    Query query;
    Criteria criteria;
    private E entity;

    //E entity -> Vai ser uma instancia do objeto (new Produto(), new Cliente())
    public GenericDao(E entity) {
        this.entity = entity;
    }

    @Override
    public void salvar(E obj) {
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            transaction = session.beginTransaction();
            session.save(obj);
            transaction.commit();
        } catch (HibernateException e) {
            System.err.println(e.getMessage());
            transaction.rollback();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    @Override
    public void excluir(E obj) {
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            transaction = session.beginTransaction();
            session.delete(obj);
            transaction.commit();

        } catch (HibernateException e) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Não foi possível Excluir, consulte o Administrador do Sistema.",null));
            System.err.println(e.getMessage());
            transaction.rollback();
          
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    @Override
    public void alterar(E obj) {
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            transaction = session.beginTransaction();
            session.update(obj);
            transaction.commit();

        } catch (HibernateException e) {
            System.err.println(e.getMessage());
            transaction.rollback();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    @Override
    public E findByCod(Integer id) throws Exception {
        session = HibernateUtil.getSessionFactory().openSession();
        @SuppressWarnings("unchecked")
        E classe = (E) session.get(entity.getClass(), id);
        session.close();
        return classe;
    }

    @Override
    public List<E> findAll() throws Exception {
        session = HibernateUtil.getSessionFactory().openSession();
        criteria = session.createCriteria(entity.getClass());
        //Inclui essa linha porque estava duplicando registro na permissão de usuario.
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        @SuppressWarnings("unchecked")
        List<E> lista = criteria.list();
        session.close();
        return lista;
    }
}
